package cn.fl.infside.service.impl;

import cmm.comm.facade.framework.api.ISysDictionaryApiService;
import cmm.mid.core.framework.page.KeyValueVO;
import cn.cmm.base.framework.context.ApplicationContextAccessor;
import cn.cmm.base.framework.exception.BaseException;
import cn.cmm.base.framework.utils.*;
import cn.cmm.mq.framework.message.MessageBodyModel;
import cn.cmm.mq.framework.message.MessageBuilder;
import cn.cmm.mq.framework.producer.service.IProducerService;
import cn.fl.capital.constant.CapitalConstant;
import cn.fl.capital.dto.CapFundDTO;
import cn.fl.capital.service.ICapFundApiService;
import cn.fl.infside.service.ReceiptInterface;
import cn.fl.infside.utils.ServiceXmlUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.rocketmq.client.exception.MQClientException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @Description: 收款明细webservice
 * @Author: liurong
 * @CreateDate: 2019/1/8 9:25
 * @Version: 1.0
 */
public class ReceiptServiceImpl implements ReceiptInterface {

    private static final Logger logger = LoggerFactory.getLogger(ReceiptServiceImpl.class);

    private IProducerService producerService = (IProducerService) ApplicationContextAccessor.getBean("producerServiceImpl");

    //private ICapFundApiService capFundService = (ICapFundApiService) ApplicationContextAccessor.getBean("capFundApiService");

    // 数据字典service
    private ISysDictionaryApiService sysDictionaryApiService = (ISysDictionaryApiService) ApplicationContextAccessor.getBean("sysDictionaryApiService");

    // 需要过滤的账户列表
    private List<KeyValueVO> kvList = new ArrayList<>();

    @Override
    public String detaiList(String xmlString) throws Exception {
        Long start = System.currentTimeMillis();
        BaseLogUtils.info(logger, "detaiList", start + "====webservice接口detaiList====拜特同步收款明细开始xmlString================"+ xmlString);
        List<Map<String, Object>> list = ServiceXmlUtils.xmlElements(xmlString);
        Long end = System.currentTimeMillis();
        BaseLogUtils.info(logger, "detaiList", start + "====webservice接口detaiList====拜特同步收款明细解析xml耗时："+(end-start)+"ms");
        if (CollectionUtils.isNotEmpty(list)) {
            // 查询数据字典中需要过滤的账号
            kvList = searchCdList(CapitalConstant.CODE_EXAC_CD);
            StringBuffer stb = new StringBuffer("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
            stb.append("<ROOT>");
            for (Map<String, Object> map : list) {
                try {
                    // 参数校验
                    if (checkParams(map, stb)) {
                        // 排除指定收款账号的数据，例如：15000092874828
                        if (excludeAccNo(map, stb)) {
                            continue;
                        }

                        //接收到数据先放入MQ中，等待消费，立即返回成功给拜特
                        stb.append("<ZDATA>");
                        stb.append("<SERIAL_ID>").append(map.get("SERIAL_ID")).append("</SERIAL_ID>");
                        CapFundDTO dto = new CapFundDTO();
                        dto.setComeCode(map.get("OPP_ACC_NO").toString());
                        dto.setComeName(map.get("OPP_ACC_NAME").toString());
                        dto.setAcceptCode(map.get("BANK_ACC").toString());
                        dto.setAcceptName(map.get("ACC_NAME").toString());
                        Long amount = DecimalUtils.convertYuanToFen(Double.valueOf(map.get("AMT").toString()));
                        dto.setAmount(amount);
                        dto.setAvailableAmount(amount);
                        Date date = DateUtils.formatStringToDate(map.get("TRIANS_TIME").toString(), DateUtils.YYYYMMDD);
                        dto.setAcceptDate(date);
                        dto.setAcceptActualDate(date);
                        // 资金来源：0-正常来款
                        dto.setFundSourcesCd(CapitalConstant.CODE_CAP_FUND_SRC_C);
                        // 资金录入方式：6-拜特导入
                        dto.setFundInputCd(CapitalConstant.CODE_CAP_FUND_INPUT_CD_6);
                        dto.setBusinessCode(map.get("SERIAL_ID").toString());
                        // 摘要信息
                        if (map.containsKey("ABS") && StringUtils.isNotBlank(map.get("ABS").toString())) {
                            dto.setDocketRem(map.get("ABS").toString());
                        }
                        // 附言信息
                        if (map.containsKey("POSTSCRIPT") && StringUtils.isNotBlank(map.get("POSTSCRIPT").toString())) {
                            if (StringUtils.isNotBlank(dto.getDocketRem())) {
                                dto.setDocketRem(dto.getDocketRem() + "_" + map.get("POSTSCRIPT"));
                            } else {
                                dto.setDocketRem(map.get("POSTSCRIPT").toString());
                            }
                        }
                        //来款渠道
                        dto.setFundChnCd(CapitalConstant.FUND_CHN_CD_CAP_BYTTER_INPUT);
                        //生产资金mq消息
                        boolean flag = this.sendFundMsg(dto);
                        if(flag){
                            stb.append("<STATUS>").append("S").append("</STATUS>");
                            stb.append("<MESSAGE>").append("新增成功").append("</MESSAGE>");
                        }else{
                            stb.append("<STATUS>").append("F").append("</STATUS>");
                            stb.append("<MESSAGE>").append("新增失败").append("</MESSAGE>");
                        }
                        stb.append("</ZDATA>");
                    }
                } catch (Exception e) {
                    BaseLogUtils.error(logger, "detaiList", "====webservice接口detaiList====拜特同步收款明细异常" + JSON.toJSONString(map), e);
                }
            }
            stb.append("</ROOT>");
            end = System.currentTimeMillis();
            BaseLogUtils.info(logger, "detaiList", start + "====webservice接口detaiList====拜特同步收款明细结束，总耗时：" + (end-start) +"ms");
            return stb.toString();
        } else {
            BaseLogUtils.error(logger, "detaiList", start + "====webservice接口detaiList====拜特同步收款明细解析xml异常结束");
            return "解析错误";
        }
    }

    /**
     * 校验参数
     *
     * @param map
     * @param stb
     * @return
     */
    private boolean checkParams(Map<String, Object> map, StringBuffer stb) {
        boolean flag = true;
        StringBuffer s = new StringBuffer();
        if (StringUtils.isBlank((String) map.get("SERIAL_ID"))) {
            flag = false;
            s.append("SERIAL_ID不能为空 ");
        }
        if (StringUtils.isBlank((String) map.get("BANK_ACC"))) {
            flag = false;
            s.append("BANK_ACC不能为空 ");
        }
        if (StringUtils.isBlank((String) map.get("ACC_NAME"))) {
            flag = false;
            s.append("ACC_NAME不能为空 ");
        }
        if (StringUtils.isBlank((String) map.get("TRIANS_TIME"))) {
            flag = false;
            s.append("TRIANS_TIME不能为空 ");
        }
        if (!flag) {
            stb.append("<ZDATA>");
            stb.append("<SERIAL_ID>").append(map.get("SERIAL_ID")).append("</SERIAL_ID>");
            stb.append("<STATUS>").append("F").append("</STATUS>");
            stb.append("<MESSAGE>").append(s).append("</MESSAGE>");
            stb.append("</ZDATA>");
        }
        return flag;
    }

    /**
     * 排除指定收款账号的数据
     *
     * @param map
     * @param stb
     * @return
     */
    private boolean excludeAccNo(Map<String, Object> map, StringBuffer stb) {
        if (StringUtils.isNotBlank((String) map.get("BANK_ACC"))
                && CollectionUtils.isNotEmpty(kvList)) {
            for (KeyValueVO kv : kvList) {
                if (kv.getKey().equals(map.get("BANK_ACC"))) {
                    stb.append("<ZDATA>");
                    stb.append("<SERIAL_ID>").append(map.get("SERIAL_ID")).append("</SERIAL_ID>");
                    stb.append("<STATUS>").append("S").append("</STATUS>");
                    stb.append("<MESSAGE>").append("新增成功.").append("</MESSAGE>");
                    stb.append("</ZDATA>");
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 查询数据字典
     *
     * @param groupCd
     * @return
     */
    public List<KeyValueVO> searchCdList(String groupCd) {
        return sysDictionaryApiService.getKvList(groupCd, CapitalConstant.SYSCD, CapitalConstant.SYSORG);
    }

    private boolean sendFundMsg(CapFundDTO capFundDTO) throws BaseException {
        MessageBuilder msgBuilder = new MessageBuilder();
        try {
            msgBuilder.setTopic("fl-biz-mq");
            msgBuilder.setTag("baite-fund-data-sync");
            msgBuilder.setKey(capFundDTO.getBusinessCode());
            MessageBodyModel message = new MessageBodyModel();
            message.setId(capFundDTO.getBusinessCode());
            message.addMessageBody("fund", capFundDTO);
            msgBuilder.setMessage(message);
            producerService.sendNormalMsg(msgBuilder);
        } catch (MQClientException e) {
            BaseLogUtils.error(logger, "sendFundMsg", "MQ发送拜特资金消息异常,数据同步失败" + JSON.toJSONString(capFundDTO), e);
            return false;
        } catch (Exception e) {
            BaseLogUtils.error(logger, "sendFundMsg", "MQ发送拜特资金消息异常,数据同步失败" + JSON.toJSONString(capFundDTO), e);
            return false;
        }
        return true;
    }

}
